package com.gitee.wsl.mathematics.vector.vec3


import com.gitee.wsl.mathematics.vector.Vector
import com.gitee.wsl.mathematics.vector.VectorD
import com.gitee.wsl.mathematics.vector.VectorF
import com.gitee.wsl.mathematics.vector.vec2.Vector2
import com.gitee.wsl.mathematics.vector.vec4.Vector4

typealias Vec3F = Vector3<Float,*>

typealias Vec3D = Vector3<Double,*>

interface Vector3<T:Number,V: Vector3<T, V>>: Vector<T, V> {

    val vec2 get() = createVec2(x,y)
    val vec3 get() =  this
    val vec4: Vector4<T, *>

    val xy get() = createVec2(x,y)
    val xz get() = createVec2(x,z)
    val yz get() = createVec2(y,z)

    fun createVec2(a:T,b:T):Vector2<T, *>

    val x:T
        get() = proxy[0]

    val y:T
        get() = proxy[1]

     val z
        get() = proxy[2]


    override val squaredLength get() = x * x + y * y + z * z

    override fun create(values: List<T>):V = create(values[0],values[1],values[2])

    fun create(x:T,y:T,z:T):V

/*
    override operator fun div(other: V) :V = create(x / other.x, y / other.y, z / other.z)
    override operator fun times(other: V) :V =create(x * other.x, y * other.y, z * other.z)
    override operator fun rem(other: V) :V= create(x % other.x, y % other.y, z % other.z)


    override val abs get() = create(abs(x), abs(y), abs(z))
    override val sign get() = create(sign(x), sign(y), sign(z))
    override val ceil get() = create(ceil(x), ceil(y), ceil(z))
    override val floor get() = create(floor(x), floor(y), floor(z))
    override val round get() = create(round(x), round(y), round(z))

    override operator fun plus(other: V) :V = create(x + other.x, y + other.y,z+other.z)

    override operator fun minus(other: V) :V = create(x - other.x, y - other.y,z-other.z)

    override operator fun times(a: Number) :V = create(x * a.toDouble(), y * a.toDouble(), z * a.toDouble())


    override operator fun div(a: Number) :V = create(x / a.toDouble(), y / a.toDouble(), z / a.toDouble())

    override        fun divBy(a: Number) :V= create( x.divBy(a),  y.divBy(a),  z.divBy(a))

    override operator fun rem(a: Number):V= create(x % a.toDouble(), y % a.toDouble(), z % a.toDouble())

    override fun remBy(a: Number) :V= create( x.remBy(a),  y.remBy(a),  z.remBy(a))

    override operator fun unaryMinus() : V = create(-x, -y, -z)*/

    operator fun component1() = x
    operator fun component2() = y
    operator fun component3() = z

}


interface Vector3F<V: Vector3<Float, V>>: Vector3<Float, V>, VectorF<V> {

}

interface Vector3D<V: Vector3<Double, V>>: Vector3<Double, V>, VectorD<V> {

}
